/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *  SRVGetJPGFrameOperation.m - iPhoneSRV console for Surveyor SRV-1 and SVS 
 *
 *  Created by Nick Kitchener.  Copyright (C) 2009  Surveyor Corporation 
 *            and Nick Kitchener.  All rights reserved.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details (www.gnu.org/licenses)
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#import "SRVGetJPGFrameOperation.h"

@implementation SRVGetJPGFrameOperation

-(id)init {
	if( self = [super init] ) {
		complete = NO;
		state = READINGHEADER;
		imageSize = 0;
		request = [[SRVStreamingRequestBuffer alloc] init];
		responseHeader = [[SRVStreamingFixedLengthBinaryResponseBuffer alloc] init];
		[responseHeader setResponseLength:10];
		responseBody = nil;
		
		NSString *reqString = [NSString stringWithUTF8String:"I"];
		[request setRequestString:reqString];
	}
	return self;
}

-(void)dealloc {
	[request release];
	request = nil;
	[responseHeader release];
	responseHeader = nil;
	if(responseBody!=nil) {
		[responseBody release];
		responseBody = nil;
	}
	[super dealloc];
}

-(void)haveBytes:(CFReadStreamRef)inputStream
{
	switch(state) {
		case READINGHEADER:
			[responseHeader haveBytes:inputStream];
			if( [responseHeader isComplete]) {
				uint8_t s0,s1,s2,s3;
				uint8_t *b;
				[responseHeader getResponse:&b];
				s0 = b[6] & 0xff;
				s1 = b[7] & 0xff;
				s2 = b[8] & 0xff;
				s3 = b[9] & 0xff;
				imageSize = s0 | s1<<8 | s2<<16 | s3<<24;
				free(b); // b was malloc'd.
				responseBody = [SRVStreamingFixedLengthBinaryResponseBuffer alloc];
				[responseBody setResponseLength:imageSize]; 
				state = READINGBODY;
			}
			break;
		case READINGBODY:
			[responseBody haveBytes:inputStream];
			if([responseBody isComplete]) {
				state = COMPLETE;
				complete = YES;
			}
	}
}

-(void)haveSpace:(CFWriteStreamRef)outputStream {
	[request haveSpace:outputStream];
}


// Stream commands
/*-(void)haveBytes:(NSInputStream*)inputStream
{
	switch(state) {
		case READINGHEADER:
			[responseHeader haveBytes:inputStream];
			if([responseHeader isComplete]) {
				uint8_t s0,s1,s2,s3;
				uint8_t *b;
				[responseHeader getResponse:&b];
				s0 = b[6] & 0xff;
				s1 = b[7] & 0xff;
				s2 = b[8] & 0xff;
				s3 = b[9] & 0xff;
				imageSize = s0 | s1<<8 | s2<<16 | s3<<24;
				responseBody = [SRVStreamingFixedLengthBinaryResponseBuffer alloc];
				[responseBody setResponseLength:imageSize]; 
				//[responseBody insertInitalData:b length:10]; 
				state = READINGBODY;
//				NSLog(@"JPEG header read complete: expecting jpeg size of %i bytes.", imageSize);
			}
			break;
		case READINGBODY:
			[responseBody haveBytes:inputStream];
			if([responseBody isComplete]) {
//				NSLog(@"JPEG body read complete.");
				// JPG complete, held in responseBody (including header)
				state = COMPLETE;
				complete = YES;
			}
	}
}

-(void)haveSpace:(NSOutputStream*)inputStream
{
	[request haveSpace:inputStream];
}*/

-(void)haveError
{
}

-(NSData*) data {
	unsigned char *frameData; 
	[responseBody getResponse:&frameData];
	return [NSData dataWithBytesNoCopy:frameData length:imageSize freeWhenDone:YES];
	//return [NSData dataWithBytes:frameData length:imageSize];
}

-(void) dumpToFile:(NSString *)filename {
//	unsigned char *frameData; 
//	[responseBody getResponse:&frameData];
//	NSData *data = [NSData dataWithBytesNoCopy:frameData length:imageSize];
	
	NSFileManager *fm=[NSFileManager defaultManager];
	[fm createFileAtPath:filename contents:[self data] attributes:nil];
}

//
// 00000000 00000000 00000000 00000000 .................
//
-(void) dumpJPG:(unsigned char*)img len:(int)len {
	
	FILE *trace = fopen("/Users/Nick/Desktop/JPGDump.log", "w");
	fprintf(trace, "JPG dump size=%i\n", len);
	
	int totalBytesToDump = len;
	int hexDumpOffset=0;
	int charDumpOffset=0;
	
	//            01234567890123456789012345678901234567890
	fprintf(trace, "AAAA: 0 1 2 3  4 5 6 7  8 9 A B  C D E F  0123 4567 89AB CDEF\n");
	fprintf(trace, "----: |------- -------- -------- -------| ---- ---- ---- ----\n");
	
	while(totalBytesToDump>0) {
		fprintf(trace, "%04.4x: ", hexDumpOffset);
		
		int bytesToDump = (totalBytesToDump>=16)?16:totalBytesToDump;
		totalBytesToDump-=bytesToDump;
		
		// dump a line
		int hexBytes = bytesToDump;
		int charBytes = bytesToDump;
		
		int hexLinePos=0;
		int linePos=0;
		while(hexBytes--) {
			fprintf(trace, "%02.2x", (img[hexDumpOffset++]));
			hexLinePos+=2;
			linePos+=2;
			if(hexLinePos%8==0) {
				fprintf(trace, " ");
				linePos++;
			}
		}
		
		while(linePos<= 35) {
			fprintf(trace, " ");
			linePos++;
		}
		
		linePos=0;
		while(charBytes--) {
			char c=img[charDumpOffset++];
			fprintf(trace, "%c", (isalnum(c))?c:'.');
			linePos++;
			if(linePos%4==0) {
				fprintf(trace," ");
			}			
		}
		fprintf(trace,"\n");
	}
	fflush(trace);
	fclose(trace);
}

@end
